package com.ruoyi.repair.service.impl;

import com.ruoyi.repair.domain.StatisticsResult;
import com.ruoyi.repair.service.IStatisticsService;
import com.ruoyi.repair.mapper.JrRepairOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class StatisticsServiceImpl implements IStatisticsService {

    @Autowired
    private JrRepairOrderMapper repairOrderMapper;

    @Override
    public Map<String, StatisticsResult> getBasicStatistics(String equipmentNo, Date startDate, Date endDate) {
        // 获取维修记录数据
        List<Map<String, Object>> records = repairOrderMapper.selectRepairStatistics(equipmentNo, startDate, endDate);
        
        // 按设备编号分组
        Map<String, List<Map<String, Object>>> groupedData = records.stream()
                .collect(Collectors.groupingBy(record -> record.get("equipmentId").toString()));

        // 计算每个设备的统计量
        Map<String, StatisticsResult> result = new HashMap<>();
        
        groupedData.forEach((equipment, data) -> {
            StatisticsResult stats = new StatisticsResult();
            
            // 获取完成时长列表
            List<Double> durations = data.stream()
                    .map(record -> parseDouble(record.get("completionDuration")))
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            
            // 计算统计量
            stats.setCount((long) durations.size());
            
            if (!durations.isEmpty()) {
                // 计算平均值
                double mean = durations.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
                stats.setMean(mean);
                
                // 计算标准差
                double variance = durations.stream()
                        .mapToDouble(d -> Math.pow(d - mean, 2))
                        .average()
                        .orElse(0.0);
                stats.setStd(Math.sqrt(variance));
                
                // 计算最小值和最大值
                stats.setMin(Collections.min(durations));
                stats.setMax(Collections.max(durations));
                
                // 计算分位数
                List<Double> sortedDurations = new ArrayList<>(durations);
                Collections.sort(sortedDurations);
                stats.setPercentile25(calculatePercentile(sortedDurations, 0.25));
                stats.setPercentile50(calculatePercentile(sortedDurations, 0.5));
                stats.setPercentile75(calculatePercentile(sortedDurations, 0.75));
            }
            
            result.put(equipment, stats);
        });
        
        return result;
    }
    
    private Double parseDouble(Object value) {
        if (value == null) {
            return null;
        }
        try {
            String str = value.toString().trim();
            if (str.endsWith("分钟")) {
                str = str.substring(0, str.length() - 2);
            } else if (str.endsWith("小时")) {
                str = str.substring(0, str.length() - 2);
                return Double.parseDouble(str) * 60;
            }
            return Double.parseDouble(str);
        } catch (NumberFormatException e) {
            return null;
        }
    }
    
    private double calculatePercentile(List<Double> sortedData, double percentile) {
        int index = (int) Math.ceil(percentile * sortedData.size()) - 1;
        return sortedData.get(Math.max(0, index));
    }
} 